/*

 */
package com.ohos.connent.accountcloud.sys.modular.user.controller;

import cn.dev33.satoken.stp.SaTokenInfo;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
import com.ohos.connent.accountcloud.auth.api.SaBaseLoginUserApi;
import com.ohos.connent.accountcloud.auth.core.pojo.SaBaseLoginUser;
import com.ohos.connent.accountcloud.common.annotation.CommonLog;
import com.ohos.connent.accountcloud.common.exception.CommonException;
import com.ohos.connent.accountcloud.common.pojo.CommonResult;
import com.ohos.connent.accountcloud.common.pojo.CommonValidList;
import com.ohos.connent.accountcloud.common.util.CommonCryptogramUtil;
import com.ohos.connent.accountcloud.sys.core.enums.AuthExceptionEnum;
import com.ohos.connent.accountcloud.sys.modular.org.entity.SysOrg;
import com.ohos.connent.accountcloud.sys.modular.position.entity.SysPosition;
import com.ohos.connent.accountcloud.sys.modular.role.entity.SysRole;
import com.ohos.connent.accountcloud.sys.modular.user.entity.SysUser;
import com.ohos.connent.accountcloud.sys.modular.user.param.*;
import com.ohos.connent.accountcloud.sys.modular.user.result.*;
import com.ohos.connent.accountcloud.sys.modular.user.service.SysUserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.http.MediaType;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import javax.validation.constraints.NotEmpty;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 用户控制器
 *
 *
 **/
@Api(tags = "用户控制器")
@ApiSupport(author = "OHOSCONNECT_TEAM", order = 9)
@RestController
@Validated
@RequestMapping("/api/v1/account/user")
public class SysUserController {

    @Resource
    private SysUserService sysUserService;

    @Resource(name = "loginUserApi")
    private SaBaseLoginUserApi loginUserApi;

    /**
     * 获取用户分页
     *
     *
     */
    @ApiOperationSupport(order = 1)
    @ApiOperation("获取用户分页")
    @PostMapping("/page")
    public CommonResult<Page<SysUserResult>> page(@RequestBody @Valid SysUserPageParam sysUserPageParam) {
        Page<SysUser> page = sysUserService.page(sysUserPageParam);
        Page<SysUserResult> resultPage = new Page<>();
        resultPage.setCurrent(page.getCurrent());
        resultPage.setSize(page.getSize());
        resultPage.setTotal(page.getTotal());
        resultPage.setPages(page.getPages());
        List<SysUserResult> results = new ArrayList<>();
        page.getRecords().forEach(sysUser -> {
            SysUserIdParam sysUserIdParam = new SysUserIdParam();
            sysUserIdParam.setId(sysUser.getId());
            List<SysRole> roleList = sysUserService.ownRoleEx(sysUserIdParam);
            List<SysUserRole> userRoleList = new ArrayList<>();
            roleList.forEach(role -> {
                SysUserRole userRole = BeanUtil.toBean(role,SysUserRole.class);
                userRoleList.add(userRole);
            });
            SysUserResult sysUserResult = BeanUtil.toBean(sysUser,SysUserResult.class);
            sysUserResult.setRoleList(userRoleList);

            results.add(sysUserResult);
        });

        resultPage.setRecords(results);
        return CommonResult.data(resultPage);
    }

    /**
     * 添加用户
     *
     *
     */
    @ApiOperationSupport(order = 2)
    @ApiOperation("添加用户")
    @CommonLog("添加用户")
    @PostMapping("/add")
    public CommonResult<String> add(@RequestBody @Valid SysUserAddParam sysUserAddParam) {
        sysUserAddParam.setOrgId("1543842934270394370"); // 运维组
        sysUserAddParam.setPositionId("1543899639134019584"); // 暂定，待后续扩展
        List<String> roleList = new ArrayList<>();
        roleList.add("1787371131561328642");
        sysUserAddParam.setRoleIdList(roleList); // 默认角色运维人员
        sysUserService.add(sysUserAddParam);
        return CommonResult.ok();
    }

    /**
     * 编辑用户
     *
     *
     */
    @ApiOperationSupport(order = 3)
    @ApiOperation("编辑用户")
    @CommonLog("编辑用户")
    @PostMapping("/sys/user/edit")
    public CommonResult<String> edit(@RequestBody @Valid SysUserEditParam sysUserEditParam) {
        sysUserService.edit(sysUserEditParam);
        return CommonResult.ok();
    }

    /**
     * 删除用户
     *
     *
     */
    @ApiOperationSupport(order = 4)
    @ApiOperation("删除用户")
    @CommonLog("删除用户")
    @PostMapping("/delete")
    public CommonResult<String> delete(@RequestBody @Valid @NotEmpty(message = "集合不能为空")
                                                   List<String> sysUserIdParamList) {
        sysUserService.delete(sysUserIdParamList);
        return CommonResult.ok();
    }

    /**
     * 获取用户详情
     *
     *
     */
    @ApiOperationSupport(order = 5)
    @ApiOperation("获取用户详情")
    @PostMapping("/detail")
    public CommonResult<SysUserResult> detail(@RequestBody @Valid SysUserIdParam sysUserIdParam) {
        SysUser sysUser = sysUserService.detail(sysUserIdParam);
        List<SysRole> roleList = sysUserService.ownRoleEx(sysUserIdParam);
        List<SysUserRole> userRoleList = new ArrayList<>();
        roleList.forEach(role -> {
            SysUserRole userRole = BeanUtil.toBean(role,SysUserRole.class);
            userRoleList.add(userRole);
        });
        SysUserResult sysUserResult = BeanUtil.toBean(sysUser,SysUserResult.class);
        sysUserResult.setRoleList(userRoleList);
        return CommonResult.data(sysUserResult);
    }

    /**
     * 禁用用户
     *
     *
     **/
    @ApiOperationSupport(order = 6)
    @ApiOperation("禁用用户")
    @CommonLog("禁用用户")
    @PostMapping("/disableUser")
    public CommonResult<String> disableUser(@RequestBody SysUserIdParam sysUserIdParam) {
        sysUserService.disableUser(sysUserIdParam);
        return CommonResult.ok();
    }

    /**
     * 启用用户
     *
     *
     **/
    @ApiOperationSupport(order = 7)
    @ApiOperation("启用用户")
    @CommonLog("启用用户")
    @PostMapping("/enableUser")
    public CommonResult<String> enableUser(@RequestBody @Valid SysUserIdParam sysUserIdParam) {
        sysUserService.enableUser(sysUserIdParam);
        return CommonResult.ok();
    }

    /**
     * 重置用户密码
     *
     *
     **/
    @ApiOperationSupport(order = 8)
    @ApiOperation("重置用户密码")
    @CommonLog("重置用户密码")
    @PostMapping("/resetPassword")
    public CommonResult<String> resetPassword(@RequestBody @Valid SysUserIdParam sysUserIdParam) {
        sysUserService.resetPassword(sysUserIdParam);
        return CommonResult.ok();
    }

    /**
     * 重置用户密码
     *
     *
     **/
    @ApiOperationSupport(order = 8)
    @ApiOperation("重置用户密码")
    @CommonLog("重置用户密码")
    @PostMapping("/setPassword")
    public CommonResult<String> setPassword(@RequestBody @Valid SysUserResetPasswordParam sysUserResetPasswordParam) {
        //获取token
        SaTokenInfo tokenInfo = StpUtil.getTokenInfo();
        //获取登录用户的id
        String loginId = (String) tokenInfo.getLoginId();
        String managerPassword = sysUserResetPasswordParam.getManagerPassword();
        // SM2解密并获得前端传来的密码哈希值
        String passwordHash;
        try {
            // 解密，并做哈希值
            passwordHash = CommonCryptogramUtil.doHashValue(CommonCryptogramUtil.doSm2Decrypt(managerPassword));
        } catch (Exception e) {
            throw new CommonException(AuthExceptionEnum.PWD_DECRYPT_ERROR.getValue());
        }
        //获取登录用的信息
        SaBaseLoginUser saBaseLoginUser = loginUserApi.getUserById(loginId);
        if(ObjectUtil.isEmpty(saBaseLoginUser)) {
            throw new CommonException(AuthExceptionEnum.ACCOUNT_LOGOUT.getValue());
        }
        //判断两个密码是否一致
        if (!saBaseLoginUser.getPassword().equals(passwordHash)) {
            throw new CommonException(AuthExceptionEnum.PWD_ERROR.getValue());
        }
        sysUserService.setPassword(sysUserResetPasswordParam);
        return CommonResult.ok();
    }

    /**
     * 用户拥有角色
     *
     *
     */
    @ApiOperationSupport(order = 9)
    @ApiOperation("获取用户拥有角色")
    @PostMapping("/ownRole")
    public CommonResult<List<SysUserRole>> ownRole(@RequestBody @Valid SysUserIdParam sysUserIdParam) {
        List<SysRole> roleList = sysUserService.ownRoleEx(sysUserIdParam);
        List<SysUserRole> userRoleList = new ArrayList<>();
        roleList.forEach(role -> {
            SysUserRole userRole = BeanUtil.toBean(role,SysUserRole.class);
            userRoleList.add(userRole);
        });
        return CommonResult.data(userRoleList);
    }

    /**
     * 给用户授权角色
     *
     *
     */
    @ApiOperationSupport(order = 10)
    @ApiOperation("给用户授权角色")
    @CommonLog("给用户授权角色")
    @PostMapping("/grantRole")
    public CommonResult<String> grantRole(@RequestBody @Valid SysUserGrantRoleParam sysUserGrantRoleParam) {
        sysUserService.grantRole(sysUserGrantRoleParam);
        return CommonResult.ok();
    }

    /**
     * 获取用户拥有资源
     *
     *
     */
    @ApiOperationSupport(order = 11)
    @ApiOperation("获取用户拥有资源")
    @GetMapping("/sys/user/ownResource")
    public CommonResult<SysUserOwnResourceResult> ownResource(@Valid SysUserIdParam sysUserIdParam) {
        return CommonResult.data(sysUserService.ownResource(sysUserIdParam));
    }

    /**
     * 给用户授权资源
     *
     *
     */
    @ApiOperationSupport(order = 12)
    @ApiOperation("给用户授权资源")
    @CommonLog("给用户授权资源")
    @PostMapping("/sys/user/grantResource")
    public CommonResult<String> grantResource(@RequestBody @Valid SysUserGrantResourceParam sysUserGrantResourceParam) {
        sysUserService.grantResource(sysUserGrantResourceParam);
        return CommonResult.ok();
    }

    /**
     * 获取用户拥有权限
     *
     *
     */
    @ApiOperationSupport(order = 13)
    @ApiOperation("获取用户拥有权限")
    @GetMapping("/sys/user/ownPermission")
    public CommonResult<SysUserOwnPermissionResult> ownPermission(@Valid SysUserIdParam sysUserIdParam) {
        return CommonResult.data(sysUserService.ownPermission(sysUserIdParam));
    }

    /**
     * 给用户授权权限
     *
     *
     */
    @ApiOperationSupport(order = 14)
    @ApiOperation("给用户授权权限")
    @CommonLog("给用户授权权限")
    @PostMapping("/sys/user/grantPermission")
    public CommonResult<String> grantPermission(@RequestBody @Valid SysUserGrantPermissionParam sysUserGrantPermissionParam) {
        sysUserService.grantPermission(sysUserGrantPermissionParam);
        return CommonResult.ok();
    }

    /**
     * 下载用户导入模板
     *
     *
     */
    @ApiOperationSupport(order = 15)
    @ApiOperation("下载用户导入模板")
    @CommonLog("下载用户导入模板")
    @GetMapping(value = "/sys/user/downloadImportUserTemplate", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
    public void downloadImportUserTemplate(HttpServletResponse response) throws IOException {
        sysUserService.downloadImportUserTemplate(response);
    }

    /**
     * 用户导入
     *
     *
     */
    @ApiOperationSupport(order = 16)
    @ApiOperation("用户导入")
    @CommonLog("用户导入")
    @PostMapping("/sys/user/import")
    public CommonResult<JSONObject> importUser(@RequestPart("file") @ApiParam(value="文件", required = true) MultipartFile file) {
        return CommonResult.data(sysUserService.importUser(file));
    }

    /**
     * 用户导出
     *
     *
     */
    @ApiOperationSupport(order = 17)
    @ApiOperation("用户导出")
    @CommonLog("用户导出")
    @GetMapping(value = "/sys/user/export", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
    public void exportUser(SysUserExportParam sysUserExportParam, HttpServletResponse response) throws IOException {
        sysUserService.exportUser(sysUserExportParam, response);
    }

    /**
     * 按模板导出用户个人信息
     *
     *
     */
    @ApiOperationSupport(order = 18)
    @ApiOperation("导出用户个人信息")
    @CommonLog("导出用户个人信息")
    @GetMapping(value = "/sys/user/exportUserInfo", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
    public void exportUserInfo(SysUserIdParam sysUserIdParam, HttpServletResponse response) throws IOException {
        sysUserService.exportUserInfo(sysUserIdParam, response);
    }

    /* ====用户部分所需要用到的选择器==== */

    /**
     * 获取组织树选择器
     *
     *
     */
    @ApiOperationSupport(order = 19)
    @ApiOperation("获取组织树选择器")
    @GetMapping("/sys/user/orgTreeSelector")
    public CommonResult<List<Tree<String>>> orgTreeSelector() {
        return CommonResult.data(sysUserService.orgTreeSelector());
    }

    /**
     * 获取组织列表选择器
     *
     *
     */
    @ApiOperationSupport(order = 20)
    @ApiOperation("获取组织列表选择器")
    @GetMapping("/sys/user/orgListSelector")
    public CommonResult<Page<SysOrg>> orgListSelector(SysUserSelectorOrgListParam sysUserSelectorOrgListParam) {
        return CommonResult.data(sysUserService.orgListSelector(sysUserSelectorOrgListParam));
    }

    /**
     * 获取职位选择器
     *
     *
     */
    @ApiOperationSupport(order = 21)
    @ApiOperation("获取职位选择器")
    @GetMapping("/sys/user/positionSelector")
    public CommonResult<Page<SysPosition>> positionSelector(SysUserSelectorPositionParam sysUserSelectorPositionParam) {
        return CommonResult.data(sysUserService.positionSelector(sysUserSelectorPositionParam));
    }

    /**
     * 获取角色选择器
     *
     *
     */
    @ApiOperationSupport(order = 22)
    @ApiOperation("获取角色选择器")
    @GetMapping("/sys/user/roleSelector")
    public CommonResult<Page<SysRole>> roleSelector(SysUserSelectorRoleParam sysUserSelectorRoleParam) {
        return CommonResult.data(sysUserService.roleSelector(sysUserSelectorRoleParam));
    }

    /**
     * 获取用户选择器
     *
     *
     */
    @ApiOperationSupport(order = 23)
    @ApiOperation("获取用户选择器")
    @GetMapping("/sys/user/userSelector")
    public CommonResult<Page<SysUser>> userSelector(SysUserSelectorUserParam sysUserSelectorUserParam) {
        return CommonResult.data(sysUserService.userSelector(sysUserSelectorUserParam));
    }
}
